﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Discio
{
    public static class Extensions
    {
        private const string ValidType = "string";

        public static void Update<T>(this IEnumerable<T> source, Action<T> callback)
        {
            if (source == null) { 
                throw new ArgumentNullException("source");
            
            }

            if (typeof(T).IsValueType)
            {
                throw new NotSupportedException("value type elements are not supported by update.");
            }
                 
            foreach (T element in source)
            {
                callback(element);
           
            }
       
        }

        public static List<T> EncryptHelper<T>(this List<T> items)
        {
            return items.Select(m => m.EncryptHelper()).ToList();
        }

        public static T EncryptHelper<T>(this T item)
        {
            foreach (var p in item.GetType().GetProperties())
            {
                var m = (EncryptColumn[])p.GetCustomAttributes(typeof(EncryptColumn), false);
                
                if (m.Length <= 0) continue;

                if (p.PropertyType.Name.ToLower() != ValidType) continue;

                if (m[0].Behavior != true) continue;

                string text = item.GetType().GetProperty(p.Name).GetValue(item, null).ToString();
                item.GetType().GetProperty(p.Name).SetValue(item, text.AESEncrypt(), null);
            }

            return item;
        }

        /// <summary>
        /// Encrypt a string using the local AES encryption class
        /// </summary>
        /// <param name="text">Text</param>
        /// <returns>Encrypted text</returns>
        public static string AESEncrypt(this string text)
        {
            AES enc = new AES();

            return enc.EncryptToString(text);
        }

        /// <summary>
        /// Decrypt a string previously encrypted by the local AES encryption class
        /// </summary>
        /// <param name="text">Encrypted text</param>
        /// <returns>Decrypted text</returns>
        public static string AESDecrypt(this string text)
        {
            AES enc = new AES();

            return enc.DecryptString(text);
        }

        /// <summary>
        /// Decrypt helper
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="item"></param>
        /// <returns></returns>
        public static T DecryptHelper<T>(this T item)
        {
            foreach (var p in item.GetType().GetProperties())
            {
                EncryptColumn[] m = (EncryptColumn[])p.GetCustomAttributes(typeof(EncryptColumn), false);
                if (m.Length > 0)
                {
                    if (p.PropertyType.Name.ToLower() == ValidType && m[0].Behavior == true)
                    {
                        string text = item.GetType().GetProperty(p.Name).GetValue(item, null).ToString();
                        string decrypt = "";
                       
                        decrypt = text.AESDecrypt();
                        text = decrypt;
                      
                        item.GetType().GetProperty(p.Name).SetValue(item, text, null);
                    }
                }
            }

            return item;
        }

    }
}
